/**
 * 
 */
package org.compiere.model;

import java.math.BigDecimal;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Владелец
 *
 */

public class CalculateCFP {
	
	private static final int CountMonthInYear = 12;
	private static final int MagicNumberForMonth = 0;
	private static Logger log = Logger.getLogger(CalculateCFP.class.getName());
	private static int[] dayOfMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
	
	private Date fromDate;
	private Date toDate;
	private Date currentDate;
	private BigDecimal amount;

	public CalculateCFP(double amount, Date fromDate, Date toDate, Date currentDate) {
		super();
		setAmount(new BigDecimal(amount));
		setFromDate(fromDate);
		setToDate(toDate);
		setCurrentDate(currentDate);
	}
	
	public CalculateCFP(double amount, Date fromDate, Date toDate) {
		super();
		setAmount(new BigDecimal(amount));
		setFromDate(fromDate);
		setToDate(toDate);
	}
	
	public CalculateCFP(double amount) {
		super();
		setAmount(new BigDecimal(amount));
	}
	
	public Date getFromDate() {
		return fromDate;
	}

	public void setFromDate(Date fromDate) {
		this.fromDate = fromDate;
	}

	public Date getToDate() {
		return toDate;
	}

	public void setToDate(Date toDate) {
		this.toDate = toDate;
	}
	
	public Date getCurrentDate() {
		return currentDate;
	}


	public BigDecimal getAmount() {
		return amount;
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount;
	}

	public void setCurrentDate(Date currentDate) {
		this.currentDate = currentDate;
	}
	
	public BigDecimal getAmountMonth() {
		BigDecimal result = new BigDecimal(0);
		if (getAmount() != null) {
			result = getAmountMonth(getCurrentDate());
		}
		return result;
	}
	
	public BigDecimal getAmountMonth(Date currentDate) {
		BigDecimal result = new BigDecimal(0);
		setCurrentDate(currentDate);
		if (getFromDate() != null && currentDate.getYear() == getFromDate().getYear() && currentDate.getMonth() == getFromDate().getMonth()) {
			result = getFirstAmountMonth();
		} else if (getToDate() != null && currentDate.getYear() == getToDate().getYear() && currentDate.getMonth() == getToDate().getMonth()) {
			result = getLastAmountMonth();
		} else if (currentDate.before(toDate) ) {
			result = getDeafaultAmountMonth();
		} 
		return result;
	}
	
	public BigDecimal getDeafaultAmountMonth() {
		BigDecimal result = new BigDecimal(0);
		try {
			double monthAmount = getAmount().doubleValue() / (double) getCountMonth();
			result = new BigDecimal(monthAmount);
		} catch (Exception e) {
			log.log(Level.SEVERE,"CalculateCFP: ",e);
		} finally {
			return result;
		}
	}
	
	public BigDecimal getFirstAmountMonth() {
		BigDecimal result = new BigDecimal(0);
		try {
			if (getFromDate() != null) {
				int countDate = dayOfMonth[getFromDate().getMonth()] - getFromDate().getDate() + 1;
				double defaultAmount = getDeafaultAmountMonth().doubleValue();
				double amount = (double)countDate * defaultAmount / (double) dayOfMonth[getFromDate().getMonth()];
				result = new BigDecimal(amount);
			}
		} catch(Exception e) {
			log.log(Level.SEVERE,"CalculateCFP: ",e);
		} finally {
			return result;
		}
	}

	public BigDecimal getLastAmountMonth() {
		BigDecimal result = new BigDecimal(0);
		try {
			if (getToDate() != null && getAmount() != null) {
				double defaultAmount = getDeafaultAmountMonth().doubleValue();
				int countMonth = getCountMonth() - (1 + getMagic());
				double amount = getAmount().doubleValue() - getFirstAmountMonth().doubleValue() - (double) countMonth * defaultAmount;  
				result = new BigDecimal(amount);
			}
		} catch(Exception e) {
			log.log(Level.SEVERE,"CalculateCFP: ",e);
		} finally {
			return result;
		}
	}	
	
	public int getCountMonth() {
		int result = 0;
		Date fromDate = getFromDate();
		Date toDate = getToDate();
		int fromYear = fromDate.getYear();
		int toYear = toDate.getYear();
		int fromMonth = fromDate.getMonth();
		int toMonth = toDate.getMonth();
		int aYear = toYear - fromYear;
		result = aYear * CountMonthInYear - fromMonth + toMonth + getMagic();
		
		return result;
	}	
	
	private int getMagic() {
		int toMonth = toDate.getMonth();
		int fromDay = fromDate.getDate();
		int toDay = toDate.getDate();
		int magic = 0;
		if (fromDay == 1 && toDay >= dayOfMonth[toMonth])
			magic = 1;
		return magic;
	}
}
